// ==UserScript==
// @name    皇冠策略
// @version  1.1
// @run-at document-idle
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @match        *://*/*
// ==/UserScript==

var ip = '127.0.0.1';

var ws = null;
var username = null;
var password = null;
var eventsMap = new Map();
var gid = false;
var config = false;
const GAME_MAP = new Map()

function loadScript(url) {
    var scriptElement = document.createElement('script');
    scriptElement.setAttribute('type', 'text/javascript');
    scriptElement.setAttribute('src', url);
    document.head.appendChild(scriptElement);
}

loadScript(`https://code.jquery.com/jquery-1.12.4.min.js`);

function init() {
    if (window.location.href == "about:blank") return
    if (!gid) gid = Math.random()
    console.info("-----------------------------")
    console.info("<<<皇冠策略客户端准备就绪>>>")
    console.info("-----------------------------")
    try {
        loadJquery().then(conServer).then(login)
    } catch (e) {
        console.info(e.message)
    }
}

async function analysisPage() {
    // 判断当前网页是否被阻塞
    // 判断是否进入主页面  alert_show
    $("#C_no_btn").click()
    // 出现网络问题，点击确认按钮
    $("#C_ok_btn_system").click()
    // 退出重登
    $("#kick_ok_btn").click()

    $("#close_btn1").click()

    // 发送当前页面状态
    if (ws && ws.readyState == WebSocket.OPEN) {
        // 如果连接已经打开
        ws.send(JSON.stringify({
            action: "hg_status",
            result: {
                status: unsafeWindow.top.userData.passwd_safe ? 200 : 400,
                balance: unsafeWindow.top.userData && unsafeWindow.top.userData.maxcredit,
                username: username ? username : unsafeWindow.top.userData && unsafeWindow.top.userData.passwd_safe
            }
        }))
    }
    setTimeout(() => {
        analysisPage()
    }, 8000);
}

function login() {
    return new Promise((resolve, reject) => {
        function handler() {
            if (unsafeWindow.top.userData && unsafeWindow.top.userData.passwd_safe) {
                resolve(true)
            } else {
                let usr = document.getElementById("usr");
                let pwd = document.getElementById("pwd");
                // 如果不存在登录信息则一直等待到登录信息的出现
                if (usr && pwd && username && password) {
                    usr.value = username
                    pwd.value = password
                    document.getElementById("btn_login").click()
                } else {
                    setTimeout(() => {
                        handler()
                    }, 3000);
                }
            }
        }
        handler()
    })

}

function loadJquery() {
    return new Promise((resolve, reject) => {
        function load() {
            setTimeout(() => {
                $ = unsafeWindow.jQuery;
                if (typeof $ == "function") {
                    analysisPage()
                    console.info("jquery load success")
                    resolve(true)
                } else {
                    load()
                }
            }, 3000);
        }
        load()
    });
}

function conServer() {
    if ($("#C_ok_btn_system").length < 1) {
        setTimeout(() => {
            conServer()
        }, 2000);
        return;
    }
    console.log("绿龙HG插件正在连接服务器")
    let username = unsafeWindow.top.userData && unsafeWindow.top.userData.passwd_safe
    ws = new WebSocket(`ws://${ip}:8000/hg?username=${username}`);
    ws.onopen = function () {
        if (unsafeWindow.top.userData && unsafeWindow.top.userData.passwd_safe) {
            console.log("已登录：HG插件连接服务器成功!!!!!!")
            getInfo()
        } else {
            console.log("未登录：HG插件连接服务器成功!!!!!!")
        }
    }

    ws.onmessage = function (e) {
        let obj = JSON.parse(e.data)
        let event = eventsMap.get(obj.action)
        if (event) {
            event(obj.result)
        }
    }
    ws.onclose = function (e) {
        console.log("服务器连接失败，重连 - HG下单");
        setTimeout(() => {
            conServer(true)
        }, 5000);
    }
    ws.onerror = function (e) { }
    return new Promise((resolve, reject) => {
        resolve(true)
    })
}

function user(result) {
    username = result.username;
    password = result.password;
}

async function odds(source, game) {
    console.info("处理赔率>>>")
    let match = game.match
    let markets = game.markets
    let wtype = source.market == "all" ? "RE" : "HRE"
    // 检查盘口是否符合条件
    if (markets.length == 0) return;
    let market = false;// 应该下0盘口
    for (let m = 0; m < markets.length; m++) {
        let mk = markets[m]
        if (mk.type == "滚球让球" && parseFloat(mk.handicap) == 0 && wtype == "RE") {
            market = mk;
            break;
        }
        if (mk.type == "滚球上半场让球" && parseFloat(mk.handicap) == 0 && wtype == "HRE") {
            market = mk;
            break;
        }
    }
    if (!market) {
        console.info("盘口没有满足情况")
        return;
    };
    // 检查联赛
    let league = match.league
    if (config.leagues) {
        let lgs = config.leagues.split("\n")
        for (let i = 0; i < lgs.length; i++) {
            let item = lgs[i]
            if (item && league.indexOf(item) >= 0) {
                console.info("----黑名单终止-----")
                return;
            }
        }
    }
    console.info(`[${source.item.id}]正在查询赔率`)
    // 检测订单是否打到上限
    let limit = localStorage[`order_limit_${source.item.id}_${source.market}`]
    limit = limit ? parseInt(limit) : 0;
    if (limit && source.market == "all" && limit >= config.all_order) {
        console.info("全场订单数量已经达到上限|" + limit)
        return;
    }
    if (limit && source.market == "half" && limit >= config.half_order) {
        console.info("半场订单数量已经达到上限|" + limit)
        return;
    }

    let target = source.target
    let chose_team = target == "home" ? "H" : "C"
    let gid = market.id;
    let top = unsafeWindow.top;
    let host = location.host;
    let data = { gid, chose_team, wtype }
    let response = await fetch(`${location.protocol}//${host}/transform.php?ver=${top.ver}`, {
        "credentials": "include",
        "headers": {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
            "Content-type": "application/x-www-form-urlencoded",
            "Sec-Fetch-Dest": "empty",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Site": "same-origin",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Cookie": document.cookie
        },
        "referrer": `${location.protocol}//${host}/`,
        "body": `p=FT_order_view&${top.param}&odd_f_type=${top.userData.odd_f_type}&gid=${gid}&gtype=FT&wtype=${wtype}&chose_team=${chose_team}`,
        "method": "POST",
        "mode": "cors"
    });
    let gameData = await response.text();
    let preOrderResp = xml2json(gameData);
    if (preOrderResp.serverresponse.errormsg) {
        console.info("查询赔率失败>>>>")
    } else {
        console.info(`[${source.item.id}]查询赔率结束，开始下单`)
        // 检查赔率是否符合条件
        let ioratio = preOrderResp.serverresponse.ioratio
        let spread = preOrderResp.serverresponse.spread
        if (ioratio <= config.odds_end && ioratio >= config.odds_beg && spread == "0") {
            order(source, game, market, preOrderResp, data)
        } else {
            console.info(`盘口赔率不在匹配范围内::[${spread}]${ioratio}`)
        }
    }

}

var ordering = false;

async function order(source, game, market, preOrderResp, data) {
    try {
        let orderTime = new Date().getTime()
        let top = unsafeWindow.top;
        let host = location.host;
        let ioratio = preOrderResp.serverresponse.ioratio;
        let con = preOrderResp.serverresponse.con;
        let ratio = preOrderResp.serverresponse.ratio;
        let timestamp2 = preOrderResp.serverresponse.ts;
        // rtype :  半场客: HREC
        // rtype :  半场主: HREH
        //          p=FT_bet&uid=oy81jjhm32831063l82507b0&ver=2024-03-28-newVer_4&langx=zh-cn&odd_f_type=H&golds=100&gid=6860667&gtype=FT&wtype=ROU&rtype=ROUC&chose_team=C&ioratio=0.78&con=2&ratio=50&autoOdd=N&timestamp=1712286766405&timestamp2=1b778c7486b1c1b341baeb5d665bfcdc&isRB=Y&imp=N&ptype=&isYesterday=N&f=1R
        let body = `p=FT_bet&${unsafeWindow.top.param}n&odd_f_type=${unsafeWindow.top.userData.odd_f_type}&golds=${config.money}&gid=${data.gid}&gtype=FT&wtype=${data.wtype}&rtype=${data.wtype}${data.chose_team}&chose_team=${data.chose_team}&ioratio=${ioratio}&con=${con}&ratio=${ratio}&autoOdd=Y&timestamp=${Date.now()}&timestamp2=${timestamp2}&isRB=Y&imp=N&ptype=&isYesterday=N&f=1R`;
        let orderResp = await fetch(`${location.protocol}//${host}/transform.php?ver=${top.ver}`, {
            "headers": {
                "accept": "*/*",
                "accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
                "cache-control": "no-cache",
                "content-type": "application/x-www-form-urlencoded",
                "pragma": "no-cache",
                "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
                "sec-ch-ua-mobile": "?0",
                "sec-ch-ua-platform": "\"Windows\"",
                "sec-fetch-dest": "empty",
                "sec-fetch-mode": "cors",
                "sec-fetch-site": "same-origin",
                "Cookie": document.cookie
            },
            "referrer": `${location.protocol}//${host}/`,
            "referrerPolicy": "strict-origin-when-cross-origin",
            "body": body,
            "method": "POST",
            "mode": "cors",
            "credentials": "include"
        }).catch(err => {
            console.info("下单发生错误：" + JSON.stringify(err))
        });
        let orderRespTxt = await orderResp.text();
        // var orderxmldoc = (new DOMParser()).parseFromString(orderRespTxt, 'text/xml')
        let orderRespJson = xml2json(orderRespTxt);
        if (orderRespJson.serverresponse.errormsg) {
            console.info("下单发生错误2：" + JSON.stringify(orderRespJson.serverresponse.errormsg))
        } else {
            // 检查注单是否成功
            let ticket_id = orderRespJson.serverresponse.ticket_id
            let order = orderRespJson.serverresponse;
            let list = await getTodayWagers()
            let isFind = false
            if (list && list.length) {
                for (let i = 0; i < list.length; i++) {
                    let item = list[i]
                    if (item.w_id.indexOf(ticket_id) > 0) {
                        isFind = true;
                    }
                }
            }
            if (isFind) {
                let limit = localStorage[`order_limit_${source.item.id}_${source.market}`]
                limit = limit ? parseInt(limit) : 0
                localStorage[`order_limit_${source.item.id}_${source.market}`] = limit + 1
                console.info(ticket_id + "，已确认成功")
                ws.send(JSON.stringify({
                    action: "order_end",
                    result: {
                        orderTime: orderTime,
                        okTime: new Date().getTime(),
                        source: source,
                        game: game,
                        order: order,
                        username: unsafeWindow.top.userData.passwd_safe
                    },
                }))
                console.info(JSON.stringify({ source, game, order }))
            }
        }
    } catch (err) {
        console.info("下单发生异常：" + err.message)
    }

}

//callback下单之后
async function getTodayWagers(retry, callback) {
    let username = unsafeWindow.top.userData && unsafeWindow.top.userData.passwd_safe
    if (!ordering && username) {
        let top = unsafeWindow.top;
        let host = location.host;
        let response = await fetch(`${location.protocol}//${host}/transform.php?ver=${top.ver}`, {
            "credentials": "include",
            "headers": {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
                "Accept": "*/*",
                "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
                "Content-type": "application/x-www-form-urlencoded",
                "Sec-Fetch-Dest": "empty",
                "Sec-Fetch-Mode": "cors",
                "Sec-Fetch-Site": "same-origin",
                "Pragma": "no-cache",
                "Cache-Control": "no-cache",
                "Cookie": document.cookie
            },
            "referrer": `${location.protocol}//${host}/`,
            "body": `p=get_today_wagers&${top.param}&LS=g&selGtype=ALL&chk_cw=N&ts=${new Date().getTime()}&format=json`,
            "method": "POST",
            "mode": "cors"
        });
        let data = await response.json();
        return data.wagers
    } else {
        console.info("正在下单，跳过查询未结算")
    }
}

async function getHistoryOrders(d) {
    let top = unsafeWindow.top;
    let host = location.host;
    let username = unsafeWindow.top.userData && unsafeWindow.top.userData.passwd_safe
    if (username) {
        try {
            let dateTime = new Date().toISOString();
            if (d) dateTime = d.toISOString();;
            let date = (dateTime.split("T")[0])
            let response = await fetch(`${location.protocol}//${host}/transform.php?ver=${top.ver}`, {
                "credentials": "include",
                "headers": {
                    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
                    "Accept": "*/*",
                    "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
                    "Content-type": "application/x-www-form-urlencoded",
                    "Sec-Fetch-Dest": "empty",
                    "Sec-Fetch-Mode": "cors",
                    "Sec-Fetch-Site": "same-origin",
                    "Pragma": "no-cache",
                    "Cache-Control": "no-cache",
                    "Cookie": document.cookie
                },
                "referrer": `${location.protocol}//${host}/`,
                "body": `p=history_switch&uid=${top["userData"].uid}&langx=${top.userData.langx}&LS=c&today_gmt=${date}&gtype=ALL&tmp_flag=Y`,
                "method": "POST",
                "mode": "cors"
            });
            let gameData = await response.text();
            // var xmldoc = (new DOMParser()).parseFromString(gameData, 'text/xml')
            let preOrderResp = xml2json(gameData);
            let list = preOrderResp.serverresponse.wagers
            if (list && list.length > 0) {
                let result = [];
                if (list.length) {
                    for (let i = 0; i < list.length; i++) {
                        let wagers = list[i];
                        if (wagers.ball_act_class == "word_red") {
                            result.push(wagers)
                        }
                    }
                } else {
                    if (list.ball_act_class == "word_red") {
                        result.push(list)
                    }
                }
                if (result.length > 0) {
                    ws.send(JSON.stringify({
                        action: "hg_history",
                        result: {
                            data: result,
                            username: unsafeWindow.top.userData && unsafeWindow.top.userData.passwd_safe
                        }
                    }))
                }
            }
        } catch (e) {
            console.info(e.message)
        }
    }
    setTimeout(() => {
        if (d) {
            // 指定日期：不传参数，使用当天
            getHistoryOrders()
        } else {
            // 未指定日期，使用昨天
            let now = new Date();
            let targetDate = new Date(now.getTime() - (1000 * 60 * 60 * 24))
            getHistoryOrders(targetDate)
        }

    }, 1000 * 60 * 2);
}

function xml2json(xml) {
    return new XML.ObjTree().parseXML(xml);
}

function pre_order(list) {
    console.info("接收数据")
    let obj = list[0];
    let hgHome = obj.hgHome
    let hgAway = obj.hgAway
    let market = obj.market;
    let games = GAME_MAP.get("zh-cn")
    if (!games) return;
    console.info("处理数据>>>")
    for (let j = 0; j < games.length; j++) {
        let game = games[j];
        let match = game.match
        let home = match.home
        let away = match.away
        let period = match.period
        let ts = period.split("^")[0]
        let marketT = ts == "1H" ? "half" : "all"
        if (home == hgHome && away == hgAway) {
            if (market != marketT) {
                console.info(`盘口匹配失败:${market} >> ${marketT}`)
                return;
            }
            odds(obj, game)
            return
        }
    }
    console.info("比赛匹配失败")
}

function setting(data) {
    config = data
    console.info("配置已更新")
}

eventsMap.set("odds", odds);
eventsMap.set("user", user);
eventsMap.set("order", order);
eventsMap.set("pre_order", pre_order)
eventsMap.set("setting", setting)

function getInfo() {
    let info = {
        cookie: document.cookie,
        ver: unsafeWindow.top.userData.ver,
        param: unsafeWindow.top.param,
        host: location.host
    }
    ws.send(JSON.stringify({
        action: "info",
        result: info
    }))
}


async function gameList(lang) {
    let v = unsafeWindow.top.param;
    if (lang == "en-us") {
        v = v.replace("&langx=zh-cn", "&langx=" + lang);
    }
    if (lang == "zh-cn") {
        v = v.replace("&langx=en-us", "&langx=" + lang);
    }
    fetch(`https://${location.host}/transform.php?ver=` + unsafeWindow.top.userData.ver, {
        "credentials": "include",
        "headers": {
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0",
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
            "Content-type": "application/x-www-form-urlencoded",
            "Sec-Fetch-Dest": "empty",
            "Sec-Fetch-Mode": "cors",
            "Sec-Fetch-Site": "same-origin"
        },
        "referrer": `https://${location.host}/`,
        "body": v + "&p=get_game_list&p3type=&date=&gtype=ft&showtype=live&rtype=rrnou&ltype=3&cupFantasy=N&sorttype=L&specialClick=&isFantasy=N&ts=" + new Date().getTime(),
        "method": "POST",
        "mode": "cors"
    }).then(response => {
        return response.text()
    }).then(text => {
        let obj = xml2json(text)
        let result = getData(obj)
        let list = {
            list: result,
            time: new Date().getTime()
        }
        GAME_MAP.set(lang, list)
        let gameListData = gameListHandler()
        if (gameListData) {
            // 发送比赛数据
            sendData(gameListData)
        }
    }).catch(err => { console.info("获取比赛数据失败：" + err.message) });
    // 判断ws是否断开
    if (!ws || ws.readyState != WebSocket.OPEN) {
        return
    }
    setTimeout(() => {
        if (lang == "en-us") {
            gameList("zh-cn")
        } else {
            gameList("en-us")
        }
    }, 5000);
}

function gameListHandler() {
    let zhList = GAME_MAP.get("zh-cn");
    let enList = GAME_MAP.get("en-us");
    let isZhNew = zhList.time > enList.time ? true : false;
    if (zhList && enList) {
        const enMap = new Map();
        // 用英文列表建立 match.id 映射
        for (const item of enList.list) {
            enMap.set(item.match.id, item);
        }
        const mergedList = [];

        for (const zhItem of zhList.list) {
            const id = zhItem.match.id;
            const enItem = enMap.get(id);
            if (!enItem) continue; // 如果找不到英文对应，跳过 
            const merged = {
                match: {
                    id: id,
                    zh: {
                        league: zhItem.match.league,
                        home: zhItem.match.home,
                        away: zhItem.match.away
                    },
                    en: {
                        league: enItem.match.league,
                        home: enItem.match.home,
                        away: enItem.match.away
                    },
                    homeScore: isZhNew ? zhItem.match.homeScore : enItem.match.homeScore,
                    awayScore: isZhNew ? zhItem.match.awayScore : enItem.match.awayScore,
                    homeRed: isZhNew ? zhItem.match.homeRed : enItem.match.homeRed,
                    awayRed: isZhNew ? zhItem.match.awayRed : enItem.match.awayRed,
                    period: isZhNew ? zhItem.match.period : enItem.match.period
                },
                markets: isZhNew ? zhItem.markets : enItem.markets  // 市场信息可以直接用中文的（如果内容一样）
            };
            mergedList.push(merged);
        }
        return mergedList.length > 0 ? mergedList : false;
    }
    return false
}



// 发送比赛数据
function sendData(list) {
    if (ws && ws.readyState == WebSocket.OPEN) {
        // 如果连接已经打开
        ws.send(JSON.stringify({
            action: "game_list",
            result: {
                list: list,
                username: unsafeWindow.top.userData.passwd_safe
            }
        }))
    }
}


function loopTodayWagers() {
    getTodayWagers()
    setTimeout(() => {
        loopTodayWagers()
    }, 1000 * 60 * 1);
}



init();


function getData(data) {
    let dataResult = []
    let list = data.serverresponse.ec;
    if (!list.length) list = [list]
    for (let i = 0; i < list.length; i++) {
        let item = list[i]
        let game = item.game
        let id = item.game.GID;
        if (id) {
            let league = game.LEAGUE;
            if (league.indexOf("EFootball - ") == 0 || league.indexOf("电竞足球") == 0) {
                continue;
            }
            let home = game.TEAM_H
            let away = game.TEAM_C
            let homeScore = game.SCORE_H;
            let awayScore = game.SCORE_C;
            let homeRed = game.REDCARD_H
            let awayRed = game.REDCARD_C
            let period = game.RETIMESET
            let systemTime = game.SYSTIME
            let datetime = game.DATETIME
            let markets = []
            // 强队标识 重要：处理数据过程：将hdp作为主队的让球数，也就是在使用hdp的时候，hdp的值代表的是主队的让球/受让
            let strong = game.STRONG

            // 全场让球  盘口1
            let handicap = game.RATIO_RE
            if (handicap) {
                let market = getMarket("all_hdp_", "滚球让球", handicap, game.IOR_REH, game.IOR_REC, strong, game.GID)
                markets.push(market);
            }
            // 全场让球  盘口2
            handicap = game.A_sub_RATIO_RE
            strong = game.A_sub_STRONG
            if (handicap) {
                let market = getMarket("all_hdp_", "滚球让球", handicap, game.A_sub_IOR_REH, game.A_sub_IOR_REC, strong, game.A_sub_GID)
                markets.push(market);
            }
            // 全场让球  盘口3
            handicap = game.B_sub_RATIO_RE
            strong = game.B_sub_STRONG
            if (handicap) {
                let market = getMarket("all_hdp_", "滚球让球", handicap, game.B_sub_IOR_REH, game.B_sub_IOR_REC, strong, game.B_sub_GID)
                markets.push(market);
            }

            // 半场让球  盘口1
            handicap = game.RATIO_HRE
            strong = game.HSTRONG
            if (handicap) {
                let market = getMarket("1h_hdp_", "滚球上半场让球", handicap, game.IOR_HREH, game.IOR_HREC, strong, game.HGID)
                markets.push(market);
            }
            // 半场让球  盘口2
            handicap = game.A_sub_RATIO_HRE
            strong = game.A_sub_HSTRONG
            if (handicap) {
                let market = getMarket("1h_hdp_", "滚球上半场让球", handicap, game.A_sub_IOR_HREH, game.A_sub_IOR_HREC, strong, game.A_sub_HGID)
                markets.push(market);
            }
            // 半场让球  盘口3
            handicap = game.B_sub_RATIO_HRE
            strong = game.B_sub_HSTRONG
            if (handicap) {
                let market = getMarket("1h_hdp_", "滚球上半场让球", handicap, game.B_sub_IOR_HREH, game.B_sub_IOR_HREC, strong, game.B_sub_HGID)
                markets.push(market);
            }
            //RATIO_ROUO 全场大小 盘口1
            handicap = game.RATIO_ROUO
            if (handicap) {
                let market = getMarket("all_ou_", "滚球大小", handicap, game.IOR_ROUC, game.IOR_ROUH, false, game.GID)
                markets.push(market);
            }
            //RATIO_ROUO 全场大小 盘口2
            handicap = game.A_sub_RATIO_ROUO
            if (handicap) {
                let market = getMarket("all_ou_", "滚球大小", handicap, game.A_sub_IOR_ROUC, game.A_sub_IOR_ROUH, false, game.A_sub_GID)
                markets.push(market);
            }
            //RATIO_ROUO 全场大小 盘口3
            handicap = game.B_sub_RATIO_ROUO
            if (handicap) {
                let market = getMarket("all_ou_", "滚球大小", handicap, game.B_sub_IOR_ROUC, game.B_sub_IOR_ROUH, false, game.B_sub_GID)
                markets.push(market);
            }


            handicap = game.RATIO_HROUO
            if (handicap) {
                let market = getMarket("1h_ou_", "滚球上半场大小", handicap, game.IOR_HROUC, game.IOR_HROUH, false, game.GID)
                markets.push(market);
            }
            //RATIO_ROUO 全场大小 盘口2
            handicap = game.A_sub_RATIO_HROUO
            if (handicap) {
                let market = getMarket("1h_ou_", "滚球上半场大小", handicap, game.A_sub_IOR_HROUC, game.A_sub_IOR_HROUH, false, game.A_sub_HGID)
                markets.push(market);
            }
            //RATIO_ROUO 全场大小 盘口3
            handicap = game.B_sub_RATIO_ROUO
            if (handicap) {
                let market = getMarket("1h_ou_", "滚球上半场大小", handicap, game.B_sub_IOR_HROUC, game.B_sub_IOR_HROUH, false, game.B_sub_HGID)
                markets.push(market);
            }
            let match = {
                id, league, home, away, homeScore, awayScore, homeRed, awayRed, period,
            }
            let result = {
                match, markets
            }
            dataResult.push(result)
        }
    }
    return dataResult;
}

function getMarket(id, type, handicap, home, away, strong, gid) {
    let hdp = handicap.split(" / ")
    if (hdp.length == 2) {
        hdp = (parseFloat(hdp[0]) + parseFloat(hdp[1])) / 2
    } else {
        hdp = hdp[0]
    }
    if (hdp != "0" && strong) {
        if (strong == "H") {
            hdp = "-" + hdp;
        }
    }
    return {
        id: gid,// 盘口
        type: type,
        handicap: hdp + "",
        homeOdds: home ? parseFloat(home).toFixed(2) : "",
        awayOdds: away ? parseFloat(away).toFixed(2) : ""
    }
}

// ========================================================================
//  XML.ObjTree -- XML source code from/to JavaScript object like E4X
// ========================================================================

if (typeof (XML) == 'undefined') XML = function () { };

//  constructor

XML.ObjTree = function () {
    return this;
};

//  class variables

XML.ObjTree.VERSION = "0.23";

//  object prototype

XML.ObjTree.prototype.xmlDecl = '<?xml version="1.0" encoding="UTF-8" ?>\n';
XML.ObjTree.prototype.attr_prefix = '-';

//  method: parseXML( xmlsource )

XML.ObjTree.prototype.parseXML = function (xml) {
    var root;
    if (window.DOMParser) {
        var xmldom = new DOMParser();
        //      xmldom.async = false;           // DOMParser is always sync-mode
        var dom = xmldom.parseFromString(xml, "application/xml");
        if (!dom) return;
        root = dom.documentElement;
    } else if (window.ActiveXObject) {
        xmldom = new ActiveXObject('Microsoft.XMLDOM');
        xmldom.async = false;
        xmldom.loadXML(xml);
        root = xmldom.documentElement;
    }
    if (!root) return;
    return this.parseDOM(root);
};

//  method: parseHTTP( url, options, callback )

XML.ObjTree.prototype.parseHTTP = function (url, options, callback) {
    var myopt = {};
    for (var key in options) {
        myopt[key] = options[key];                  // copy object
    }
    if (!myopt.method) {
        if (typeof (myopt.postBody) == "undefined" &&
            typeof (myopt.postbody) == "undefined" &&
            typeof (myopt.parameters) == "undefined") {
            myopt.method = "get";
        } else {
            myopt.method = "post";
        }
    }
    if (callback) {
        myopt.asynchronous = true;                  // async-mode
        var __this = this;
        var __func = callback;
        var __save = myopt.onComplete;
        myopt.onComplete = function (trans) {
            var tree;
            if (trans && trans.responseXML && trans.responseXML.documentElement) {
                tree = __this.parseDOM(trans.responseXML.documentElement);
            }
            __func(tree, trans);
            if (__save) __save(trans);
        };
    } else {
        myopt.asynchronous = false;                 // sync-mode
    }
    var trans;
    if (typeof (HTTP) != "undefined" && HTTP.Request) {
        myopt.uri = url;
        var req = new HTTP.Request(myopt);        // JSAN
        if (req) trans = req.transport;
    } else if (typeof (Ajax) != "undefined" && Ajax.Request) {
        var req = new Ajax.Request(url, myopt);   // ptorotype.js
        if (req) trans = req.transport;
    }
    if (callback) return trans;
    if (trans && trans.responseXML && trans.responseXML.documentElement) {
        return this.parseDOM(trans.responseXML.documentElement);
    }
}

//  method: parseDOM( documentroot )

XML.ObjTree.prototype.parseDOM = function (root) {
    if (!root) return;

    this.__force_array = {};
    if (this.force_array) {
        for (var i = 0; i < this.force_array.length; i++) {
            this.__force_array[this.force_array[i]] = 1;
        }
    }

    var json = this.parseElement(root);   // parse root node
    if (this.__force_array[root.nodeName]) {
        json = [json];
    }
    if (root.nodeType != 11) {            // DOCUMENT_FRAGMENT_NODE
        var tmp = {};
        tmp[root.nodeName] = json;          // root nodeName
        json = tmp;
    }
    return json;
};

//  method: parseElement( element )

XML.ObjTree.prototype.parseElement = function (elem) {
    //  COMMENT_NODE
    if (elem.nodeType == 7) {
        return;
    }

    //  TEXT_NODE CDATA_SECTION_NODE
    if (elem.nodeType == 3 || elem.nodeType == 4) {
        var bool = elem.nodeValue.match(/[^\x00-\x20]/);
        if (bool == null) return;     // ignore white spaces
        return elem.nodeValue;
    }

    var retval;
    var cnt = {};

    //  parse attributes
    if (elem.attributes && elem.attributes.length) {
        retval = {};
        for (var i = 0; i < elem.attributes.length; i++) {
            var key = elem.attributes[i].nodeName;
            if (typeof (key) != "string") continue;
            var val = elem.attributes[i].nodeValue;
            if (!val) continue;
            key = this.attr_prefix + key;
            if (typeof (cnt[key]) == "undefined") cnt[key] = 0;
            cnt[key]++;
            this.addNode(retval, key, cnt[key], val);
        }
    }

    //  parse child nodes (recursive)
    if (elem.childNodes && elem.childNodes.length) {
        var textonly = true;
        if (retval) textonly = false;        // some attributes exists
        for (var i = 0; i < elem.childNodes.length && textonly; i++) {
            var ntype = elem.childNodes[i].nodeType;
            if (ntype == 3 || ntype == 4) continue;
            textonly = false;
        }
        if (textonly) {
            if (!retval) retval = "";
            for (var i = 0; i < elem.childNodes.length; i++) {
                retval += elem.childNodes[i].nodeValue;
            }
        } else {
            if (!retval) retval = {};
            for (var i = 0; i < elem.childNodes.length; i++) {
                var key = elem.childNodes[i].nodeName;
                if (typeof (key) != "string") continue;
                var val = this.parseElement(elem.childNodes[i]);
                if (!val) continue;
                if (typeof (cnt[key]) == "undefined") cnt[key] = 0;
                cnt[key]++;
                this.addNode(retval, key, cnt[key], val);
            }
        }
    }
    return retval;
};

//  method: addNode( hash, key, count, value )

XML.ObjTree.prototype.addNode = function (hash, key, cnts, val) {
    if (this.__force_array[key]) {
        if (cnts == 1) hash[key] = [];
        hash[key][hash[key].length] = val;      // push
    } else if (cnts == 1) {                   // 1st sibling
        hash[key] = val;
    } else if (cnts == 2) {                   // 2nd sibling
        hash[key] = [hash[key], val];
    } else {                                    // 3rd sibling and more
        hash[key][hash[key].length] = val;
    }
};

//  method: writeXML( tree )

XML.ObjTree.prototype.writeXML = function (tree) {
    var xml = this.hash_to_xml(null, tree);
    return this.xmlDecl + xml;
};

//  method: hash_to_xml( tagName, tree )

XML.ObjTree.prototype.hash_to_xml = function (name, tree) {
    var elem = [];
    var attr = [];
    for (var key in tree) {
        if (!tree.hasOwnProperty(key)) continue;
        var val = tree[key];
        if (key.charAt(0) != this.attr_prefix) {
            if (typeof (val) == "undefined" || val == null) {
                elem[elem.length] = "<" + key + " />";
            } else if (typeof (val) == "object" && val.constructor == Array) {
                elem[elem.length] = this.array_to_xml(key, val);
            } else if (typeof (val) == "object") {
                elem[elem.length] = this.hash_to_xml(key, val);
            } else {
                elem[elem.length] = this.scalar_to_xml(key, val);
            }
        } else {
            attr[attr.length] = " " + (key.substring(1)) + '="' + (this.xml_escape(val)) + '"';
        }
    }
    var jattr = attr.join("");
    var jelem = elem.join("");
    if (typeof (name) == "undefined" || name == null) {
        // no tag
    } else if (elem.length > 0) {
        if (jelem.match(/\n/)) {
            jelem = "<" + name + jattr + ">\n" + jelem + "</" + name + ">\n";
        } else {
            jelem = "<" + name + jattr + ">" + jelem + "</" + name + ">\n";
        }
    } else {
        jelem = "<" + name + jattr + " />\n";
    }
    return jelem;
};

//  method: array_to_xml( tagName, array )

XML.ObjTree.prototype.array_to_xml = function (name, array) {
    var out = [];
    for (var i = 0; i < array.length; i++) {
        var val = array[i];
        if (typeof (val) == "undefined" || val == null) {
            out[out.length] = "<" + name + " />";
        } else if (typeof (val) == "object" && val.constructor == Array) {
            out[out.length] = this.array_to_xml(name, val);
        } else if (typeof (val) == "object") {
            out[out.length] = this.hash_to_xml(name, val);
        } else {
            out[out.length] = this.scalar_to_xml(name, val);
        }
    }
    return out.join("");
};

//  method: scalar_to_xml( tagName, text )

XML.ObjTree.prototype.scalar_to_xml = function (name, text) {
    if (name == "#text") {
        return this.xml_escape(text);
    } else {
        return "<" + name + ">" + this.xml_escape(text) + "</" + name + ">\n";
    }
};

//  method: xml_escape( text )

XML.ObjTree.prototype.xml_escape = function (text) {
    return (text + '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
};


